using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

public enum ShapeState //形状的种类分类枚举
{
    L_shape,
    Z_shape,
    T_shape,
    I_shape,
}

public class Pattern : MonoBehaviour
{
    public ShapeState _shapeState;
    private RotationPattern _rotationPattern;

    private List<Vector2> currentPatternPos = new List<Vector2>();
    private int index = 0; //当前图形的当前旋转编号

    private void Start()
    {
        _rotationPattern = GetComponent<RotationPattern>();
    }


    public void RotationSelf()
    {
        //当前下落到的位置
        Transform tempTrans = GameManager.Instance.board.BoardCells[currentPatternPos[0]].transform;

        Debug.Log("当前物体的长度为 " + currentPatternPos.Count);
        index = index++ >= currentPatternPos.Count - 1 ? 0 : index++;
        // index++;
        // if (index >= _rotationPattern.patternPositionInfo.Count)
        //     index = 0;

        //List<Vector2> temp = _rotationPattern.GetCurrentPatternPosition(index);
        ////这句有 bug 为什么？？？？？？？？？？？？？？？？  因为 List 是引用类型传递

        List<Vector2> temp = _rotationPattern.CreateFourPatternPosition(_shapeState, index);
        for (int i = 0; i < temp.Count; i++) //把位置改成正在下落的坐标
        {
            temp[i] += new Vector2(tempTrans.position.x, tempTrans.position.y);
        }

        for (int i = 0; i < temp.Count; i++)
        {
            if (IsFallGroundOrFallFixed(temp[i]) || IsExtraEdge(temp[i]))
            {
                //Debug.Log("有触底或者超界");
                return;
            }
        }

        for (int i = 0; i < currentPatternPos.Count; i++) //把旧的隐藏
        {
            HideOtherCell(currentPatternPos[i]);
        }

        currentPatternPos.Clear();
        currentPatternPos = temp; //新的画出来
        Draw();
    }

    public void LeftOrRightMove(Vector2 direction)
    {
        for (int i = 0; i < currentPatternPos.Count; i++)
        {
            //如果目标位置超界了，就 return
            if (IsExtraEdge(currentPatternPos[i] + direction))
                return;
        }

        //没超界，就左或者右移动
        for (int i = 0; i < currentPatternPos.Count; i++)
        {
            HideOtherCell(currentPatternPos[i]);
            currentPatternPos[i] += direction;
        }

        Draw();
    }

    bool IsExtraEdge(Vector2 patternPosCell) //判断是否超界，以及对左右两边是否已经固定物体的判断
    {
        if (patternPosCell.x < 0 || patternPosCell.x >= GameManager.Instance.weight)
            return true;
        if (GameManager.Instance.board.BoardCells.ContainsKey(patternPosCell) &&
            GameManager.Instance.board.BoardCells[patternPosCell]._cellState == CellState.Fixed)
            return true;
        return false;
    }

    public void Falling() //自动向下落
    {
        bool isFixed = false;
        for (int i = 0; i < currentPatternPos.Count; i++)
        {
            //如果目标位置触底了，就 return
            if (IsFallGroundOrFallFixed(currentPatternPos[i] - new Vector2(0, 1)))
            {
                isFixed = true;
                break;
            }
        }

        if (!isFixed) //没有触底，往下落
        {
            for (int i = 0; i < currentPatternPos.Count; i++)
            {
                HideOtherCell(currentPatternPos[i]);
                currentPatternPos[i] -= new Vector2(0, 1);
            }
        }
        else //目标的位置触底了，那就固定
        {
            Fixed();
        }

        Draw();
    }

    //是否到底了，或者是否碰到了其他固定的格子
    //参数是，Board 上指定的那个位置的格子，是否到底了或者是固定的格子
    bool IsFallGroundOrFallFixed(Vector2 patternPosCell)
    {
        if (GameManager.Instance.board.BoardCells.ContainsKey(patternPosCell) &&
            GameManager.Instance.board.BoardCells[patternPosCell]._cellState == CellState.Fixed)
            return true;
        return patternPosCell.y < 0;
    }

    void Fixed()
    {
        for (int i = 0; i < currentPatternPos.Count; i++)
            if (GameManager.Instance.board.BoardCells.ContainsKey(currentPatternPos[i]))
                GameManager.Instance.board.BoardCells[currentPatternPos[i]]._cellState = CellState.Fixed;

        GameManager.Instance.isGameOver = IsFallTop();
        currentPatternPos.Clear();
        GameManager.Instance.board.ClearCell();
        CreateNewPattern();
    }

    bool IsFallTop()
    {
        if (GameManager.Instance.board
                .BoardCells[new Vector2((int)GameManager.Instance.weight * 0.5f, GameManager.Instance.height - 1)]
                ._cellState == CellState.Fixed
            || GameManager.Instance.board
                .BoardCells[new Vector2((int)GameManager.Instance.weight * 0.5f + 1, GameManager.Instance.height - 1)]
                ._cellState == CellState.Fixed
            || GameManager.Instance.board
                .BoardCells[new Vector2((int)GameManager.Instance.weight * 0.5f - 1, GameManager.Instance.height - 1)]
                ._cellState == CellState.Fixed)
        {
            Debug.Log("顶了，游戏结束");
            return true;
        }

        return false;
    }

    void Draw() //画到棋盘上面，参数是其他需要关闭显示的格子列表
    {
        foreach (Vector2 everyPos in currentPatternPos)
        {
            if (!IsFallTop() && GameManager.Instance.board.BoardCells.ContainsKey(everyPos))
                GameManager.Instance.board.BoardCells[everyPos]._cellState = CellState.HighLight;
        }
    }

    void HideOtherCell(Vector2 pos) //将其他指定的格子隐藏
    {
        if (GameManager.Instance.board.BoardCells.ContainsKey(pos))
            GameManager.Instance.board.BoardCells[pos]._cellState = CellState.Hide;
    }

    public void CreateNewPattern() //创建一个新的图形 
    {
        RandomShape();
        currentPatternPos = _rotationPattern.CreateFourPatternPosition(_shapeState, index); //确定是哪一个形状
        for (int i = 0; i < currentPatternPos.Count; i++) //把新生的形状放到最上面的初始位置
            currentPatternPos[i] += new Vector2(GameManager.Instance.worldPos.position.x,
                GameManager.Instance.worldPos.position.y);
        Draw();
    }

    void RandomShape() //随机选定一个形状
    {
        int number = Random.Range(0, 4);
        switch (number)
        {
            case 0:
                _shapeState = ShapeState.L_shape;
                break;
            case 1:
                _shapeState = ShapeState.Z_shape;
                break;
            case 2:
                _shapeState = ShapeState.T_shape;
                break;
            case 3:
                _shapeState = ShapeState.I_shape;
                break;
            default:
                _shapeState = ShapeState.L_shape;
                break;
        }
    }
}